package com.coda.service.impl;

import com.coda.adminVo.apartment.ApartmentDetailVo;
import com.coda.adminVo.apartment.ApartmentItemVo;
import com.coda.adminVo.apartment.ApartmentQueryVo;
import com.coda.adminVo.apartment.ApartmentSubmitVo;
import com.coda.adminVo.fee.FeeValueVo;
import com.coda.adminVo.graph.GraphVo;
import com.coda.constant.MessageConstant;
import com.coda.constant.StatusConstant;
import com.coda.entity.*;
import com.coda.exception.DeletionNotAllowedException;
import com.coda.exception.GlobalExceptionHandler;
import com.coda.exception.StatusIsStartException;
import com.coda.mapper.ApartmentMapper;
import com.coda.mapper.RegionInfoMapper;
import com.coda.mapper.RoomMapper;
import com.coda.result.PageResult;
import com.coda.service.ApartmentService;
import com.coda.service.RegionInfoService;
import com.github.pagehelper.IPage;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;

@Service
public class ApartmentServiceImpl implements ApartmentService {
    @Autowired
    private ApartmentMapper apartmentMapper;
    @Autowired
    private RegionInfoMapper regionInfoMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * 保存或更新公寓信息
     *
     * @param apartmentSubmitVo
     */
    @Override
    public void saveOrUpdate(ApartmentSubmitVo apartmentSubmitVo) {

        //判断是否有id，有：update，没有：insert
        if (apartmentSubmitVo.getId() == null) {
            //拷贝对象
            ApartmentInfo apartmentInfo = new ApartmentInfo();
            BeanUtils.copyProperties(apartmentSubmitVo, apartmentInfo);
            apartmentInfo.setIsRelease(StatusConstant.DISABLE);

            transactionTemplate.execute(status -> {
                //设置省，市，县名称
                setRegion(apartmentSubmitVo, apartmentInfo);
                //插入公寓基本信息
                apartmentMapper.insertApartmentInfo(apartmentInfo);

                //插入公寓详细信息
                setApartmentDetail(apartmentSubmitVo, apartmentInfo);
                return null;
            });


        } else {
            //更新数据
            ApartmentInfo apartmentinfo = new ApartmentInfo();
            BeanUtils.copyProperties(apartmentSubmitVo, apartmentinfo);

            transactionTemplate.execute(status -> {
                //设置省，市，县名称
                setRegion(apartmentSubmitVo, apartmentinfo);
                apartmentMapper.updateApatrment(apartmentinfo);

                //先删除原先关联公寓的信息
                Long id = apartmentinfo.getId();
                removeApartmentDetail(id);

                //插入公寓详细信息
                setApartmentDetail(apartmentSubmitVo, apartmentinfo);
                return null;
            });

        }

    }

    /**
     * 该方法用于插入更新或添加的数据
     */
    private void setApartmentDetail(ApartmentSubmitVo apartmentSubmitVo, ApartmentInfo apartmentInfo) {
        //获取请求中传递过来的图片信息
        List<GraphVo> graphVoList = apartmentSubmitVo.getGraphVoList();
        //创建集合用于存放图片对象
        List<GraphInfo> graphInfoList = new ArrayList<>();
        //遍历封装进实体类
        for (GraphVo graphVo : graphVoList) {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setName(graphVo.getName());
            graphInfo.setUrl(graphVo.getUrl());
            graphInfo.setItemId(apartmentInfo.getId());
            graphInfo.setItemType(StatusConstant.APARTMENT);
            graphInfoList.add(graphInfo);
        }
        //id插入图片信息
        apartmentMapper.insertGraphInfo(graphInfoList);


        //获取请求集合中的配套信息id
        List<Long> facilityInfoIds = apartmentSubmitVo.getFacilityInfoIds();
        if (!(CollectionUtils.isEmpty(facilityInfoIds))) {
            //创建集合，用户存放每次遍历添加的配套信息
            List<ApartmentFacility> apartmentFacilityList = new ArrayList<>();
            //遍历请求集合中的配套信息id，依次封装进公寓配套关系实体类
            for (Long facilityInfoId : facilityInfoIds) {
                ApartmentFacility apartmentFacility = ApartmentFacility.builder()
                        .apartmentId(apartmentInfo.getId())
                        .facilityId(facilityInfoId).build();
                apartmentFacilityList.add(apartmentFacility);
            }
            //插入公寓配套关系信息
            apartmentMapper.insertAparFacility(apartmentFacilityList);
        }

        //获取请求中的标签id集合
        List<Long> labelIds = apartmentSubmitVo.getLabelIds();
        if (!(CollectionUtils.isEmpty(labelIds))) {
            //创建集合用于存放每次添加的公寓标签关系
            List<ApartmentLabel> apartmentLabelList = new ArrayList<>();
            //循环遍历依次添加
            for (Long labelId : labelIds) {
                ApartmentLabel apartmentLabel = ApartmentLabel.builder()
                        .apartmentId(apartmentInfo.getId())
                        .labelId(labelId).build();
                apartmentLabelList.add(apartmentLabel);
            }
            //插入公寓和标签关系
            apartmentMapper.insertApartmentLabel(apartmentLabelList);
        }

        //获取请求中的杂费id
        List<Long> feeValueIds = apartmentSubmitVo.getFeeValueIds();
        if (!(CollectionUtils.isEmpty(feeValueIds))) {
            //创建集合用于存放每次添加的公寓杂费关系
            List<ApartmentFeeValue> apartmentFeeValueList = new ArrayList<>();
            //依次添加公寓和杂费关系
            for (Long feeValueId : feeValueIds) {
                ApartmentFeeValue apartmentFeeValue = ApartmentFeeValue.builder()
                        .apartmentId(apartmentInfo.getId())
                        .feeValueId(feeValueId).build();
                apartmentFeeValueList.add(apartmentFeeValue);
            }
            //插入公寓和杂费关系
            apartmentMapper.insertApartmentFeeValue(apartmentFeeValueList);
        }
    }

    /**
     * 该方法用于添加地区name进vo对象
     */
    private void setRegion(ApartmentSubmitVo apartmentSubmitVo, ApartmentInfo apartmentInfo) {
        //获取地区name
        CityInfo cityInfo = regionInfoMapper.getCity(apartmentSubmitVo.getCityId());
        DistrictInfo districtInfo = regionInfoMapper.getDistrict(apartmentSubmitVo.getDistrictId());
        ProvinceInfo provinceInfo = regionInfoMapper.getProvince(apartmentSubmitVo.getProvinceId());
        //赋值
        apartmentInfo.setCityName(cityInfo.getName());
        apartmentInfo.setDistrictName(districtInfo.getName());
        apartmentInfo.setProvinceName(provinceInfo.getName());
    }

    /**
     * 该方法用于删除公寓对应的详细信息
     */
    private void removeApartmentDetail(Long id) {
        apartmentMapper.deleteApartmentFacility(id);
        apartmentMapper.deleteGraphinfo(id);
        apartmentMapper.deleteApartmentLabel(id);
        apartmentMapper.deleteApartmentFeeValue(id);
    }

    /**
     * 条件分页查询公寓列表
     *
     * @param apartmentQueryVo
     * @return
     */
    @Override
    public PageResult pagelist(Integer current, Integer size, ApartmentQueryVo apartmentQueryVo) {
        //设置分页参数
        PageHelper.startPage(current, size);
        //条件查询
        Page<ApartmentItemVo> pageList = apartmentMapper.page(apartmentQueryVo);

        for (ApartmentItemVo apartmentItemVo : pageList) {
            //获取房间总数
            Long roomSumCount = roomMapper.getRoomSumCount(apartmentItemVo.getId());
            //获取空闲房间数
            Long FreeRoomCount = roomMapper.getFreeRoomCount();
            apartmentItemVo.setTotalRoomCount(roomSumCount);
            apartmentItemVo.setFreeRoomCount(FreeRoomCount);
        }
        PageResult pageResult = new PageResult(pageList.getTotal(), pageList.getResult());

        return pageResult;
    }

    /**
     * 根据id获取公寓详细信息
     *
     * @return
     */
    @Override
    public ApartmentDetailVo getDetailById(Long id) {
        //获取公寓信息
        ApartmentDetailVo apartmentDetailVo = apartmentMapper.getApartmentDetail(id);

        //根据公寓id获取图片信息
        List<GraphVo> graphVo = apartmentMapper.getGraph(id);
        //根据公寓id获取标签信息
        List<LabelInfo> labelInfo = apartmentMapper.getLabel(id);
        //根据公寓id获取配套信息
        List<FacilityInfo> facilityInfo = apartmentMapper.getFacilityInfo(id);
        ////根据公寓id获取杂费信息
        List<FeeValueVo> feeValue = apartmentMapper.getFeeValue(id);

        //赋值进vo对象
        apartmentDetailVo.setGraphVoList(graphVo);
        apartmentDetailVo.setLabelInfoList(labelInfo);
        apartmentDetailVo.setFacilityInfoList(facilityInfo);
        apartmentDetailVo.setFeeValueVoList(feeValue);

        return apartmentDetailVo;
    }

    /**
     * 根据id删除公寓信息
     *
     * @param id
     */
    @Override
    public void removeById(Long id) {
        //判断公寓下是否有房间信息，如果有需要先删除房间信息
        Integer count = roomMapper.getCount(id);
        if (count > 0) {
            throw new DeletionNotAllowedException(MessageConstant.APART_RELEVANCE_ROOM);
        }
        //判断公寓是否为发布状态，发布状态不能删除
        ApartmentInfo apartment = apartmentMapper.getApartment(id);
        if (apartment.getIsRelease() == 1){
            throw new StatusIsStartException(MessageConstant.APARTMENT_IS_RELEASE);
        }

        transactionTemplate.execute(status -> {
            //删除公寓信息
            apartmentMapper.deleteApartment(id);
            //删除公寓详细信息
            removeApartmentDetail(id);
            return null;
        });

    }

    /**
     * 根据id修改房间公寓发布状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Integer status) {
        ApartmentInfo apartmentInfo = new ApartmentInfo();
        apartmentInfo.setId(id);
        apartmentInfo.setIsRelease(status);
        apartmentMapper.updateApatrment(apartmentInfo);
    }

    /**
     * 根据区县id查询公寓信息列表
     *
     * @param id
     */
    @Override
    public List<ApartmentInfo> listInfoByDistrictId(Long id) {
        List<ApartmentInfo> apartmentInfo = apartmentMapper.getApartmentByDistrictId(id);
        return apartmentInfo;
    }


}
